#pragma once

#include <string>
#include <vector>
#include <memory>
#include <utility>
#include <opencv2/opencv.hpp>

// 直接包含IPU SDK头文件
#include "mi_ipu.h"
#include "mi_ipu_datatype.h"
#include "mi_sys.h"
#include "mi_common_datatype.h"

namespace protonet {

/**
 * @brief 简化的IPU模型包装器类 - 不依赖AIEngine框架
 */
class IPUModelWrapper {
public:
    /**
     * @brief 构造函数
     * @param model_path 模型文件路径
     * @param input_size 输入图像尺寸
     */
    IPUModelWrapper(const std::string& model_path, 
                    const std::pair<int, int>& input_size = {224, 224});
    
    /**
     * @brief 析构函数
     */
    ~IPUModelWrapper();
    
    /**
     * @brief 禁用拷贝构造和赋值
     */
    IPUModelWrapper(const IPUModelWrapper&) = delete;
    IPUModelWrapper& operator=(const IPUModelWrapper&) = delete;
    
    /**
     * @brief 检查模型是否已成功加载
     * @return 是否已加载
     */
    bool isLoaded() const { return is_loaded_; }
    
    /**
     * @brief 获取输入尺寸
     * @return 输入尺寸(width, height)
     */
    std::pair<int, int> getInputSize() const { return input_size_; }
    
    /**
     * @brief 进行模型推理
     * @param input_data 预处理后的输入数据 (NHWC格式)
     * @return 特征向量
     */
    std::vector<float> infer(const std::vector<float>& input_data);
    
    /**
     * @brief 获取特征向量维度
     * @return 特征向量维度
     */
    size_t getFeatureDimension() const { return feature_dimension_; }

private:
    std::string model_path_;                   ///< 模型文件路径
    std::pair<int, int> input_size_;          ///< 输入图像尺寸
    bool is_loaded_;                          ///< 是否已加载模型
    size_t feature_dimension_;                ///< 特征向量维度
    
    // IPU相关变量
    static bool is_ipu_initialized_;          ///< IPU设备是否已初始化（全局）
    MI_U32 channel_id_;                       ///< IPU通道ID
    MI_IPU_TensorVector_t input_tensor_;      ///< 输入张量
    MI_IPU_TensorVector_t output_tensor_;     ///< 输出张量
    
    /**
     * @brief 初始化IPU设备（全局初始化）
     * @return 是否成功
     */
    bool initializeIPUDevice();
    
    /**
     * @brief 初始化模型
     * @return 是否成功
     */
    bool initializeModel();
    
    /**
     * @brief 获取张量信息
     * @return 是否成功
     */
    bool getTensorInfo();
};

} // namespace protonet